import RPS.EquivalenceMapping;
import RPS.MappingAssertion;
import RPS.MappingVariableRenamer;
import RPS.PeerSchema;
import RPS.RPS;
import Rewriting.FederationManager;
import Rewriting.SPARQLEquivalenceChecker;
import SPARQL.Utilities.SPARQLVariableRenamer;
import Rewriting.SPARQLRewriter;
import Rewriting.Source;
import Rewriting.TripleUnifier;
import SPARQL.SPARQL;
import SPARQL.Service;
import SPARQL.SimpleURI;
import SPARQL.TriplePattern;
import SPARQL.Utilities.QueryRenamer;
import SPARQL.Variable;
import com.hp.hpl.jena.query.Query;
import java.util.HashSet;
import parser.ParseException;
import parser.SparqlParser;
import java.util.Iterator;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import com.hp.hpl.jena.query.QueryFactory;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author riccardo
 */
public class Test3 {
    public static void main(String[] args) throws ParseException {
        SPARQLEquivalenceChecker equicheker = new SPARQLEquivalenceChecker();
        
        SPARQL parse = SparqlParser.parse("SELECT ?x ?y WHERE { ?x <DB2:actorInMovie> ?y } ");
        SPARQL parse2 = SparqlParser.parse("PREFIX DB2: <http://www.db2.com/>"
                + " SELECT ?x ?y WHERE { ?x <DB2:actorInMovie> <http://www.db2.com/Spiderman> . ?x <foaf:age> ?y }");
        //"SELECT ?x ?y WHERE { ?x <DB2:actorInMovie> <DB2:Toby.Maguire> . <DB2:Toby.Maguire> <foaf:age> ?y }"
        SPARQL parse5 = SparqlParser.parse("ASK {<DB2:Spideirman> <DB2:actorInMovie> <DB2:Toby.Maguire> }");
        SPARQL parse3 = SparqlParser.parse("ASK { ?x <rdf:type> <DB1:actor> }");
        SPARQL parse4 = SparqlParser.parse("ASK { ?x <rdf:type> <DB2:anActor> }");
        SPARQL parse6 = SparqlParser.parse("SELECT ?a ?b WHERE { ?a <DB1:starring> ?b } ");
        
      
        
        //SPARQL parse3 = SparqlParser.parse("ASK {<Spiderman> <starring> <Toby_Maguire>}");
        //System.out.println("set of triples are equals " + parse.getTriplePatterns().equals(parse3.getTriplePatterns()));
        SPARQL queryTest = null;
        
        SPARQL body = SparqlParser.parse("SELECT ?x ?y WHERE {?x <DB1:starring> ?y}");
        
        MappingAssertion mapping = new MappingAssertion(SparqlParser.parse("SELECT ?x ?y WHERE {?x <DB1:starring> ?y}"),
        SparqlParser.parse("SELECT ?x ?y WHERE {?x <DB2:actorInMovie> ?y}"));
        
        MappingVariableRenamer renamer1 = new MappingVariableRenamer(mapping);
        renamer1.renameVariables();
        
        renamer1.renameVariables();
        
        
        
        MappingAssertion mapping1 = new MappingAssertion(SparqlParser.parse("SELECT ?x WHERE {?x <rdf:type> <DB1:actor>}"),
        SparqlParser.parse("SELECT ?x WHERE {?x <rdf:type> <DB2:anActor>}"));
        EquivalenceMapping emapping = new EquivalenceMapping(new SimpleURI("DB1:Toby_Maguire"),
        new SimpleURI("DB2:Toby.Maguire"));
        EquivalenceMapping emapping1 = new EquivalenceMapping(new SimpleURI("foaf:Toby_Maguire"),
        new SimpleURI("DB1:Toby_Maguire"));
        EquivalenceMapping emapping2 = new EquivalenceMapping(new SimpleURI("DB1:Spiderman"),
        new SimpleURI("DB2:Spiderman"));
        RPS peerSystem = new RPS();
        PeerSchema schema1,schema2,schema3;
        schema1 = new PeerSchema();
        schema2 = new PeerSchema();
        schema3 = new PeerSchema();
        schema1.addConstant(new SimpleURI("DB1:Toby_Maguire"));
        schema1.addConstant(new SimpleURI("DB1:Spiderman"));
        schema1.addConstant(new SimpleURI("DB1:starring"));
        peerSystem.addPeerSchema(schema1);
        schema2.addConstant(new SimpleURI("DB2:Toby.Maguire"));
        schema2.addConstant(new SimpleURI("DB2:Spiderman"));
        schema2.addConstant(new SimpleURI("DB2:actorInMovie"));
        peerSystem.addPeerSchema(schema2);
        schema3.addConstant(new SimpleURI("foaf:Toby_Maguire"));
        schema3.addConstant(new SimpleURI("foaf:age"));
        peerSystem.addPeerSchema(schema3);
        Source source1, source2 = new Source(), source3 = new Source();
        source1 = new Source();
        source1.setEndpoint(new SimpleURI("http://DB1/"));
        source1.setSchema(schema1);
        source2.setEndpoint(new SimpleURI("http://DB2/"));
        source2.setSchema(schema2);
        source3.setEndpoint(new SimpleURI("http://foaf/"));
        source3.setSchema(schema3);
        FederationManager fedmanager = new FederationManager();
        fedmanager.addSource(source1);
        fedmanager.addSource(source2);
        
        fedmanager.addSource(source3);
        
        
        
        peerSystem.addEMapping(emapping);
        peerSystem.addEMapping(emapping1);
        peerSystem.addEMapping(emapping2);
        peerSystem.addGMapping(mapping);
        
        peerSystem.addGMapping(mapping1);
        
        queryTest = parse2;
        SPARQL originalQuery = (SPARQL) queryTest.clone();
        
        System.out.println(peerSystem);
        
        SPARQLRewriter rewriter = new SPARQLRewriter(peerSystem);
        Set<SPARQL> setOfQueries = rewriter.rewrite(queryTest);
        System.out.println(originalQuery);
        System.out.println("Original query: " + QueryFactory.create(originalQuery.toString()));
        System.out.println("\nRewritten query: ");
        
        Iterator<SPARQL> iterator = setOfQueries.iterator();
        while(iterator.hasNext()){
            SPARQL query = iterator.next();
            System.out.println(QueryFactory.create(query.toString()));
            if (iterator.hasNext())
            System.out.println("UNION");
            
        }
       
        System.out.println("SIZE :" + setOfQueries.size());
        Set<SPARQL> setOfQueriesFed = fedmanager.rewrite(setOfQueries);
        
        
        
 
    
        System.out.println("\nRewritten query with federation: ");
        iterator = setOfQueriesFed.iterator();
        while(iterator.hasNext()){
            SPARQL query = iterator.next();
            System.out.println(QueryFactory.create(query.toString()));
            if (iterator.hasNext())
            System.out.println("UNION");
            
        }
       
        System.out.println("SIZE :" + setOfQueriesFed.size());
 
        
 
    }
    
    
}
